#include <arch/gdt.h>
#include <arch/tss.h>
#include <mm/memregion.h>
#include <compiler.h>
#include <type.h>

#define ngdt 6
u64 gdt[ngdt];
u16 gdt_limit = sizeof(gdt) - 1;
extern tss_t tss;

static inline void set_gdt_entry(u32 index, u32 flag, u32 base, u32 limit) {
    gdt[index] = SEG_BASE_H(base) | flag | SEG_LIMIT_H(limit) | SEG_BASE_M(base);
    gdt[index] <<= 32;
    gdt[index] += SEG_BASE_L(base) | SEG_LIMIT_L(limit);
}

void init_gdt(void) {
    set_gdt_entry(0, 0, 0, 0);
    set_gdt_entry(1, R0_CODE, 0, 0xffffffff);
    set_gdt_entry(2, R0_DATA, 0, 0xffffffff);
    set_gdt_entry(3, R3_CODE, 0, 0xffffffff);
    set_gdt_entry(4, R3_DATA, 0, 0xffffffff);
    set_gdt_entry(5, TSS, (u32)&tss, sizeof(tss) - 1);
}
